package nccloud.pubimpl.ic.wastage.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.pub.env.ICBSContext;
import nc.bs.pub.common.ValueCheckUtil;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.impl.pubapp.pattern.data.vo.VOQuery;
import nc.itf.scmpub.reference.uap.pf.PfServiceScmUtil;
import nc.pubitf.ic.m4c.ISaleOutRefQuery;
import nc.pubitf.ic.m4y.ITransOutRefQuery;
import nc.ui.querytemplate.querytree.IQueryScheme;
import nc.vo.ic.m4453.entity.WastageBodyVO;
import nc.vo.ic.m4453.entity.WastageDutyFlag;
import nc.vo.ic.m4453.entity.WastagePartFlag;
import nc.vo.ic.m4453.entity.WastageVO;
import nc.vo.ic.m4c.entity.SaleOutBodyVO;
import nc.vo.ic.m4c.entity.SaleOutHeadVO;
import nc.vo.ic.m4c.entity.SaleOutVO;
import nc.vo.ic.m4y.entity.TransOutBodyVO;
import nc.vo.ic.m4y.entity.TransOutHeadVO;
import nc.vo.ic.m4y.entity.TransOutVO;
import nc.vo.ic.material.define.InvCalBodyVO;
import nc.vo.ic.material.query.InvInfoQuery;
import nc.vo.ic.pub.calc.BusiCalculator;
import nc.vo.ic.pub.util.CollectionUtils;
import nc.vo.ic.pub.util.NCBaseTypeUtils;
import nc.vo.ic.pub.util.VOEntityUtil;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.lang.UFDouble;
import nc.vo.scmpub.res.billtype.ICBillType;
import nccloud.dto.baseapp.querytree.dataformat.QueryTreeFormatVO;
import nccloud.dto.ic.pub.entity.TransVoInfo;
import nccloud.dto.ic.pub.entity.TransferInfo;
import nccloud.pubimpl.ic.wastage.deal.WastageValueSetter;
import nccloud.pubitf.ic.custrecloss.service.IWastAgeFetchBillService;
import nccloud.pubitf.platform.query.INCCloudQueryService;



public class WastAgeFetchBillServiceImpl
  implements IWastAgeFetchBillService
{
  private WastageVO[] processData(WastageVO[] vos) {
    BusiCalculator cal = BusiCalculator.getBusiCalculatorAtBS();
    for (WastageVO wastageVO : vos) {
      wastageVO.getHead().setStatus(2);
      for (int i = 0; i < wastageVO.getBodyVOs().length; i++) {
        WastageBodyVO body = wastageVO.getBodyVOs()[i];
        body.setCrowno(((i + 1) * 10) + "");
        body.setStatus(2);
        UFDouble noutsignnum = body.getNoutsignnum();
        if (null != noutsignnum) {
          
          UFDouble outsignastnum = cal.calculateAstNum(noutsignnum, body.getVchangerate(), body.getCastunitid());
          body.setNoutsignastnum(outsignastnum);
        } 
      } 
    } 
    return vos;
  }

  
  private IQueryScheme getScheme(QueryTreeFormatVO info) {
    INCCloudQueryService qt = (INCCloudQueryService)NCLocator.getInstance().lookup(INCCloudQueryService.class);
    return qt.convertCondition(info);
  }



  
  public SaleOutVO[] querySaleOutBill(IQueryScheme paramIQueryScheme) throws BusinessException {
    ISaleOutRefQuery service = (ISaleOutRefQuery)NCLocator.getInstance().lookup(ISaleOutRefQuery.class);

    SaleOutVO[] svos = service.queryBillsFor4453(paramIQueryScheme);
    
    List<SaleOutVO> volist = new ArrayList<>();
    
    if(null == svos || svos.length ==0) {
    	return svos;
    }
    for(SaleOutVO svo : svos) {
    	List<SaleOutBodyVO> bodylist = new ArrayList<>();
    	SaleOutBodyVO[]  sbvos = svo.getBodys();
    	for(SaleOutBodyVO sbvo : sbvos) {
    		if(null == sbvo.getNsignnum()) {
    			bodylist.add(sbvo);
    		}
    		if(null != sbvo.getNsignnum() && (sbvo.getNsignnum().compareTo(new UFDouble(0))) <= 0 ) {
    			bodylist.add(sbvo);
    		}
    	}
    	if(ValueCheckUtil.isNullORZeroLength(bodylist)) {
    		continue;
    	}
    	svo.setChildrenVO(bodylist.toArray(new SaleOutBodyVO[bodylist.size()]));
    	volist.add(svo);
    }
    
    
    SaleOutVO[] svosw2 = new SaleOutVO[volist.size()];
    for(int i =0; i<volist.size(); i++ ) {
    	svosw2[i] = volist.get(i);
    }
    
    
    return svosw2;
    
  }

  
  public String querySaveOutPkorg(String hid) throws BusinessException {
    ISaleOutRefQuery service = (ISaleOutRefQuery)NCLocator.getInstance().lookup(ISaleOutRefQuery.class);

    
    return service.queryPkorgFor4453(hid);
  }


  
  public WastageVO[] generateSaveOutBill(TransferInfo info) throws BusinessException {
    TransVoInfo voInfo = info.getInfo()[0];
    
    String[] hids = voInfo.getHids();
    VOQuery<SaleOutHeadVO> headQry = new VOQuery<SaleOutHeadVO>(SaleOutHeadVO.class);
    SaleOutHeadVO[] headvos = (SaleOutHeadVO[])headQry.query(hids);
    
    String[] bids = voInfo.getBids();
    VOQuery<SaleOutBodyVO> bodyQry = new VOQuery<SaleOutBodyVO>(SaleOutBodyVO.class);
    SaleOutBodyVO[] bodyvos = (SaleOutBodyVO[])bodyQry.query(bids);
    
    SaleOutVO[] vos = new SaleOutVO[headvos.length];
    for (int i = 0; i < vos.length; i++) {
      SaleOutVO vo = new SaleOutVO();
      List<SaleOutBodyVO> ownbodys = new ArrayList<SaleOutBodyVO>();
      vo.setParent(headvos[i]);
      for (SaleOutBodyVO bodyvo : bodyvos) {
        if (headvos[i].getCgeneralhid().equals(bodyvo.getCgeneralhid())) {
          ownbodys.add(bodyvo);
        }
      } 
      vo.setChildrenVO((CircularlyAccessibleValueObject[])ownbodys.toArray(new SaleOutBodyVO[0]));
      vos[i] = vo;
    } 
    WastageVO[] retvos = (WastageVO[])PfServiceScmUtil.executeVOChange(ICBillType.SaleOut
        .getCode(), ICBillType.WastageBill.getCode(), vos);
    
    return processData(retvos);
  }



  
  public TransOutVO[] queryTransOutBill(QueryTreeFormatVO info) throws BusinessException {
    IQueryScheme scheme = getScheme(info);
    ITransOutRefQuery service = (ITransOutRefQuery)NCLocator.getInstance().lookup(ITransOutRefQuery.class);
    TransOutVO[] svos = service.queryBillsFor4453(scheme);
    
    List<TransOutVO> volist = new ArrayList<>();
    if(null == svos) {
    	return svos;
    }
    for(TransOutVO svo : svos) {
    	List<TransOutBodyVO> bodylist = new ArrayList<>();
    	TransOutBodyVO[] sbvos = svo.getBodys();
    	for(TransOutBodyVO sbvo : sbvos) {
    		if(null == sbvo.getNtranoutnum()) {
    			bodylist.add(sbvo);
    		}
    		
    		if(null != sbvo.getNtranoutnum() && sbvo.getNtranoutnum().compareTo(new UFDouble(0))<=0) {
    			bodylist.add(sbvo);
    		}
    	}
    	if(ValueCheckUtil.isNullORZeroLength(bodylist)) {
    		continue;
    	}
    	svo.setChildrenVO(bodylist.toArray(new TransOutBodyVO[bodylist.size()]));
    	volist.add(svo);
    }
    
    TransOutVO[] svosw2 = new TransOutVO[volist.size()];
    for(int i = 0; i<volist.size(); i++) {
    	svosw2[i] = volist.get(i);
    }
    
    return svosw2;
  }


  
  public WastageVO[] generateTransOutBill(TransferInfo info) throws BusinessException {
    TransVoInfo voInfo = info.getInfo()[0];
    
    String[] hids = voInfo.getHids();
    VOQuery<TransOutHeadVO> headQry = new VOQuery<TransOutHeadVO>(TransOutHeadVO.class);
    TransOutHeadVO[] headvos = (TransOutHeadVO[])headQry.query(hids);
    
    String[] bids = voInfo.getBids();
    VOQuery<TransOutBodyVO> bodyQry = new VOQuery<TransOutBodyVO>(TransOutBodyVO.class);
    TransOutBodyVO[] bodyvos = (TransOutBodyVO[])bodyQry.query(bids);
    
    TransOutVO[] vos = new TransOutVO[headvos.length];
    for (int i = 0; i < vos.length; i++) {
      TransOutVO vo = new TransOutVO();
      List<TransOutBodyVO> ownbodys = new ArrayList<TransOutBodyVO>();
      vo.setParent(headvos[i]);
      for (TransOutBodyVO bodyvo : bodyvos) {
        if (headvos[i].getCgeneralhid().equals(bodyvo.getCgeneralhid())) {
          ownbodys.add(bodyvo);
        }
      } 
      vo.setChildrenVO((CircularlyAccessibleValueObject[])ownbodys.toArray(new TransOutBodyVO[0]));
      vos[i] = vo;
    } 
    WastageVO[] retvos = (WastageVO[])PfServiceScmUtil.executeVOChange(ICBillType.TransOut
        .getCode(), ICBillType.WastageBill.getCode(), vos);
    return processData(retvos);
  }



  
  public WastageVO[] generateAllBill(TransferInfo infos) throws BusinessException {
    TransVoInfo voInfo0 = infos.getInfo()[0];
    
    String[] hids0 = voInfo0.getHids();
    VOQuery<SaleOutHeadVO> headQry0 = new VOQuery<SaleOutHeadVO>(SaleOutHeadVO.class);
    SaleOutHeadVO[] headvos0 = (SaleOutHeadVO[])headQry0.query(hids0);
    
    String[] bids0 = voInfo0.getBids();
    VOQuery<SaleOutBodyVO> bodyQry0 = new VOQuery<SaleOutBodyVO>(SaleOutBodyVO.class);
    SaleOutBodyVO[] bodyvos0 = (SaleOutBodyVO[])bodyQry0.query(bids0);
    
    SaleOutVO[] vos0 = new SaleOutVO[headvos0.length];
    for (int i = 0; i < vos0.length; i++) {
      SaleOutVO vo = new SaleOutVO();
      List<SaleOutBodyVO> ownbodys = new ArrayList<SaleOutBodyVO>();
      vo.setParent(headvos0[i]);
      for (SaleOutBodyVO bodyvo : bodyvos0) {
        if (headvos0[i].getCgeneralhid().equals(bodyvo.getCgeneralhid())) {
          ownbodys.add(bodyvo);
        }
      } 
      vo.setChildrenVO((CircularlyAccessibleValueObject[])ownbodys.toArray(new SaleOutBodyVO[0]));
      vos0[i] = vo;
    } 

    
    WastageVO[] vos00 = (WastageVO[])PfServiceScmUtil.executeVOChange(ICBillType.SaleOut
        .getCode(), ICBillType.WastageBill.getCode(), vos0);
    
    TransVoInfo voInfo1 = infos.getInfo()[1];
    
    String[] hids1 = voInfo1.getHids();
    VOQuery<TransOutHeadVO> headQry1 = new VOQuery<TransOutHeadVO>(TransOutHeadVO.class);
    TransOutHeadVO[] headvos1 = (TransOutHeadVO[])headQry1.query(hids1);
    
    String[] bids1 = voInfo1.getBids();
    VOQuery<TransOutBodyVO> bodyQry1 = new VOQuery<TransOutBodyVO>(TransOutBodyVO.class);
    TransOutBodyVO[] bodyvos1 = (TransOutBodyVO[])bodyQry1.query(bids1);
    
    TransOutVO[] vos1 = new TransOutVO[headvos1.length];
    for (int i = 0; i < vos1.length; i++) {
      TransOutVO vo = new TransOutVO();
      List<TransOutBodyVO> ownbodys = new ArrayList<TransOutBodyVO>();
      vo.setParent(headvos1[i]);
      for (TransOutBodyVO bodyvo : bodyvos1) {
        if (headvos1[i].getCgeneralhid().equals(bodyvo.getCgeneralhid())) {
          ownbodys.add(bodyvo);
        }
      } 
      vo.setChildrenVO((CircularlyAccessibleValueObject[])ownbodys.toArray(new TransOutBodyVO[0]));
      vos1[i] = vo;
    } 
    WastageVO[] vos11 = (WastageVO[])PfServiceScmUtil.executeVOChange(ICBillType.TransOut
        .getCode(), ICBillType.WastageBill.getCode(), vos1);
    
    WastageVO[] retvos = new WastageVO[vos00.length + vos11.length];
    System.arraycopy(vos00, 0, retvos, 0, vos00.length);
    System.arraycopy(vos11, 0, retvos, vos00.length, vos11.length);
    
    return processData(retvos);
  }

  
  public WastageVO[] queryByHid(String[] pks) throws BusinessException {
    BillQuery<WastageVO> service = new BillQuery<WastageVO>(WastageVO.class);
    return (WastageVO[])service.query(pks);
  }














  
  private void setDefalutValue(AggregatedValueObject[] retvos) {
    for (AggregatedValueObject vo : retvos) {
      CircularlyAccessibleValueObject head = vo.getParentVO();
      head.setAttributeValue("fwastdutyflag", WastageDutyFlag.CUSTOMER
          .value());
      for (CircularlyAccessibleValueObject body : vo.getChildrenVO()) {
        body.setAttributeValue("fwastdutyflag", WastageDutyFlag.CUSTOMER
            .value());
      }
    } 
  }










  
  public void initValues(WastageVO[] vos) {
    setDefalutValue(vos);
    setNorwastNum(vos);
    WastageValueSetter valueSetter = new WastageValueSetter();
    for (WastageVO vo : vos) {
      vo = valueSetter.setBillInitData(vo);
    }
  }






  
  private void setDefalutValue(WastageVO[] vos) {
    for (WastageVO wastageVO : vos) {
      CircularlyAccessibleValueObject head = wastageVO.getParentVO();
      if (head.getAttributeValue("fwastpartflag") == null) {
        head.setAttributeValue("fwastpartflag", WastagePartFlag.TransferOut
            .value());
      }
      if (head.getAttributeValue("fwastdutyflag") == null) {
        head.setAttributeValue("fwastdutyflag", WastageDutyFlag.CUSTOMER
            .value());
        for (CircularlyAccessibleValueObject body : wastageVO.getChildrenVO()) {
          body.setAttributeValue("fwastdutyflag", WastageDutyFlag.CUSTOMER
              .value());
        }
      } 
    } 
  }





  
  private void setNorwastNum(WastageVO[] vos) {
    InvInfoQuery query = (new ICBSContext()).getInvInfo();
    for (WastageVO vo : vos) {
      String pk_calbody = vo.getHead().getPk_org();
      Set<String> cmaterialvids = VOEntityUtil.getVOsValueSet(vo.getBodyVOs(), "cmaterialvid");
      
      InvCalBodyVO[] invinfo = query.getInvCalBodyVO(pk_calbody, (String[])cmaterialvids
          .toArray(new String[0]));
      Map<String, InvCalBodyVO> invMap = CollectionUtils.hashVOArray("pk_material", invinfo);
      
      if (invMap == null || invMap.size() <= 0) {
        return;
      }
      boolean isTransferOut = (WastagePartFlag.TransferOut.value() == vo.getHead().getFwastpartflag());
      for (WastageBodyVO body : vo.getBodyVOs()) {
        UFDouble noutsignnum = body.getNoutsignnum();
        UFDouble noutnum = body.getNoutnum();
        UFDouble norwastnum = null;
        UFDouble norwastAstNum = null;
        if (NCBaseTypeUtils.isGt(noutsignnum, noutnum)) {
          norwastnum = NCBaseTypeUtils.sub(noutnum, new UFDouble[] { noutsignnum });
          norwastAstNum = NCBaseTypeUtils.sub(body.getNoutastnum(), new UFDouble[] { body.getNoutsignastnum() });
        } else if (isTransferOut) {
          
          UFDouble reasonRate = ((InvCalBodyVO)invMap.get(body.getCmaterialvid())).getReasonwasterate();
          norwastnum = NCBaseTypeUtils.mult(new UFDouble[] { body.getNoutnum(), reasonRate });
          norwastAstNum = NCBaseTypeUtils.mult(new UFDouble[] { body.getNoutastnum(), reasonRate });
        } 
        
        if (body.getNnorwastnum() == null) {

          
          body.setNnorwastnum(norwastnum);
          body.setNnorwastastnum(norwastAstNum);
        } 
      } 
    } 
  }
}